//
//  main.c
//  LexicalAnalysis
//
//  Created by ckq on 2018/4/24.
//  Copyright © 2018年 chenkq. All rights reserved.
//

#include <stdio.h>
#include <string.h>

/****************************************************************************************
 tokenType:
 1:keyword     if, while, return
 2:identifier     x, color, UP
 3:separator     }, (, ;
 4:operator     +, <, =
 5:literal     true, 6.02e23, "music"
 6:comment

****************************************************************************************/
struct Token {
    char tokenCt[200];
    int  tokenType;
};

char keywords[50][20] = {"abstract", "assert", "boolean", "break", "byte", "case", "catch", "char","class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "package", "private", "protected", "public", "return", "strictfp", "short", "static", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "try", "void", "volatile", "while"};

char literals[3][10] = {"true","false","null"};

//函数声明
int getToken(const char *restrict content,struct Token *t,int *i);
int typeOfChar(char ch);
int typeOfStr(const char *restrict str);

int main(int argc,char *argv[])
{
    FILE *fp = fopen(argv[1], "r");
    //打开源文件出错处理
    if(!fp)
    {
        printf("cann't open the file:%s \n",argv[1]);
        return -1;
    }
    //循环读取行
    while(!feof(fp))
    {
        char buffer[500];
        char *line = fgets(buffer, 500, fp);
//        printf("line:%s,buffer:%s\n",line,buffer);
        //读取行出错处理
        if(ferror(fp))
        {
            return -1;
        }
        //处理行
        if(line)
        {
//            long lineLenth = strlen(line);
            int index = 0;
            while(line[index] != '\n')
            {
                struct Token token = {"",0};
                int r = getToken(line, &token, &index);
                //返回0表示获取token成功
                if(r==0)
                {
                    printf("tokenCt:%s;tokenType:%d\n",token.tokenCt,token.tokenType);
                }
                
            }
            
        }
    }
}

//函数定义，返回0表示获取token成功，返回-1表示返回为空，其他表示获取token失败
int getToken(const char *restrict content,struct Token *t,int *i)
{
    char tokenCt[200] = "";
    int tokenType = 0;
    //忽略空格
    while(content[*i]==' '){
        (*i)++;
        if(content[*i] == '\n') return -1;
    }
    switch (typeOfChar(content[*i])) {
        case 1:
        {
            int start = *i;
            int tokenCtIndex = 0;
            while (typeOfChar(content[*i])!=0) {
                tokenCt[tokenCtIndex] = content[*i];
                tokenCtIndex++;
                (*i)++;
            }
            tokenType = typeOfStr(tokenCt);
            break;
        }
        case 2:
        {
            switch (content[*i]) {
                case '0':
                {
                  break;
                }
                default:
                    break;
            }
            (*i)++;
            break;
        }
        case 0:
        {
            (*i)++;
            break;
        }
        default:
            break;
    }
    //处理结果
    if(strcmp("", tokenCt)){
        strcpy(t->tokenCt, tokenCt);
        t->tokenType = tokenType;
        return 0;
    }else{
        return -1;
    }
}

int typeOfChar(char ch)
{
    if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch=='_')) return 1;
    if(ch>='0' && ch<='9') return 2;
    return 0;
}

//1表示关键字，2标识符,5是字面量
int typeOfStr(const char *restrict str)
{
    for(int i=0;i<sizeof(keywords);i++){
        if(!strcmp(keywords[i],str))
        {
            return 1;
        }
    }
    for(int i=0;i<sizeof(literals);i++){
        if(!strcmp(literals[i],str))
        {
            return 5;
        }
    }
    return 2;
}




